<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>深拷贝</title>
</head>

<body>
    <script>
        /*
        完全复制另外一个对象，引用也是自己创建。即完整复制舒服的值（而非引用）。目的在于避免拷贝后数据对原数据产生影响
        
        */
        /**
         * 实现深拷贝的方式
         * 1。JSON方法实现：利用JSON的parse（）和stringfy（）实现对某一个对象的深拷贝（无法处理源对象中的函数）
         * let arr = [1, 3, {username: 'kobe'}   ];
            let arr4 = JSON.parse(JSON.stringify(arr));
            arr4[2].username = 'james'; 
            console.log(arr, arr4)     //[1,3，{username:'kobe'}]     [1,3，{username:'james'}]

        */
        /**
        * 2.手写递归方法：递归方法实现深度克隆原理：遍历对象、数组直到里边都是基本数据类型(字符串(String)、数字(Number)、布尔(Boolean)、对空(Null)、未定义(Undefined))，然后再去复制，就是深度拷贝。
        引用数据类型(对象类型):对象(Object)、数组(Array)、函数(Function)。 特殊的对象:正则(RegExp)和日期(Date)需要从新递归
       */
        var obj1 = [{
            name: '臧三',
            childs: ['小明', '小芳'],
            fn: function () { return '123'},
            age: undefined
        }]

        var obj2 = extend(obj1)
        obj2[0].fn=function(){
            return '1234'
        }
        obj2[0].childs = []

        console.log(obj1, obj2)
        // console.log(obj1,obj2)
        console.log(obj1[0].fn,obj2[0].fn)
        function extend(data) {
            if (typeof data === 'object' && data) {
                console.log(typeof data.length,'typeof data.length')
                let val = typeof data.length === 'number' ? [] : {}
                for (let i in data) {
                    val[i] = extend(data[i])
                }
                return val
            } else {
                return data
            }
        }
        //3.函数库lodash：该函数库也有提供 _.cloneDeep用来做深拷贝。
        // var _ = require('lodash');
        // var obj1 = { a: 1, b: { f: { g: 1 } }, c: [1, 2, 3] };
        // var obj2 = _.cloneDeep(obj1);
        // console.log(obj1.b.f === obj2.b.f);     // false

    </script>

</body>

</html>